perm filename FILLR.SAI[PUB,SYS] blob
sn#195738 filedate 1978-01-06 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00015 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00003 00002 BEGOF("FILLR")
C00006 00003 PUBLIC SIMPLE PROCEDURE FILLR! $"#
C00007 00004 PUBLIC SIMPLE PROCEDURE APPEND(STRING CHARS) $"#
C00008 00005 PUBLIC SIMPLE PROCEDURE COMPMAXIMS $"#
C00009 00006 PUBLIC RECURSIVE PROCEDURE EMIT(STRING CHARS) $"#
C00010 00007 PUBLIC RECURSIVE PROCEDURE EMITPIECE(STRING CHARS INTEGER NCHARS, XCHARL) $"#
C00015 00008 PUBLIC SIMPLE PROCEDURE EMSPACES(INTEGER N) $"#
C00016 00009 PUBLIC SIMPLE PROCEDURE OKCR(BOOLEAN EVEN!IN!SUPERSUBSCRIPT) $"#
C00017 00010 PRIVATE SIMPLE PROCEDURE OKSP(BOOLEAN EVEN!BEFORE!LMARG) $"#
C00018 00011 PUBLIC RECURSIVE PROCEDURE PGPHSTART $"#
C00020 00012 PUBLIC STRING SIMPLE PROCEDURE SPS(INTEGER N) $"#
C00021 00013 PUBLIC INTERNAL RECURSIVE BOOLEAN PROCEDURE TEXTLINE $"#
C00025 00014 PRIVATE RECURSIVE PROCEDURE TEXTSEGMENT $"#
C00027 00015 FINISHED
C00028 ENDMK
C⊗;
BEGOF("FILLR")
COMMENT
This module fills a text line with as many words as can fit. The file
HORIZ handles positioning within a line, such as scripts, tabs, and
centering.
The routines build a first pass output line in string OWL and then
call the line paster (PLACELINE()) to place it in an area. OWL is
kept lengthy enough to hold any first pass output line. That way, a
line can be constructed by IDPB'ing (with APPEND()) inside OWL
instead of by numerous concatenations.
Characters in OWL[1 TO OAKS] belong to the current line being built.
However, some of these characters describe FONT changes or forward
label references and others mark word breaks or CR to the left margin
for superimposing. Thus, the line reaches only to column POSN
(relative to the left edge of the area), and FAKE of these columns
are not occupied but are only allocated for forward references.
In FILL mode, the last permissible point after which the line can be
broken by a CrLf is marked by four variables: BRKPT, BRKPOSN,
BRKSPCS, and BRKFAKE, which contain the values of OAKS, POSN, and
FAKE at that point, and the number of delible spaces right after that
point. Though there is normally a WDBRK character at the breakpoint,
there may be none if it is the first breakpoint on the line or if it
was caused by a hyphen.
TEXTLINE sets up the input stream for processing by TEXTSEGMENT.
TEXTSEGMENT scans it up to a {, cr, or altmode, obeying all control
characters (see SCANTEXT in file CTRLC) and EMITting all regular
characters. EMIT calls APPEND after checking for line overflow, etc.
Spaces are handled differently -- instead of calling EMIT to APPEND
them immediately, EMSPACES is called, which just counts up spaces in
SPCS and handles COMPACTion and punctuation problems. Thus, when
EMIT is called, it must append SPCS spaces before appending its
argument.
;
PROCEDURES
PUBLIC SIMPLE PROCEDURE FILLR! ;$"#
BEGIN "FILLR!"
INTEGER I ;
SPSSTR ← SP ;
FOR I ← 1 THRU 200 DO SPSSTR ← SPSSTR&SP ;
END "FILLR!" ;
PUBLIC SIMPLE PROCEDURE APPEND(STRING CHARS) ;$"#
IF ON THEN
BEGIN "APPEND"
STRING D ; INTEGER CCT, BALANCE ;
DEFINE SRC=['15], COUNT=['14], DEST=['13], CHAR=['11] ;
CCT ← LENGTH(CHARS) ;
IF (BALANCE ← LENGTH(OWL) - (OAKS+CCT)) < 0 THEN
OWL ← OWL & SP & SPS((1-BALANCE)*2) ;
IF CCT > 0 THEN
BEGIN
LABEL IUD ; COMMENT DEPOSIT LOOP ;
D ← OWL[OAKS+1 FOR 1] ;
START!CODE "APPD"
MOVE SRC, CHARS ;
HRRZ COUNT, CCT ;
ADDM COUNT, OAKS ;
MOVE DEST, D ;
IUD: ILDB CHAR, SRC ;
IDPB CHAR, DEST ;
SOJG COUNT, IUD ;
END "APPD"
END ;
END "APPEND" ;
PUBLIC SIMPLE PROCEDURE COMPMAXIMS ;$"#
BEGIN "COPYMAXIMS"
FMAXIM ← (RMARG-RIGHTIM)-LMARG ;
NMAXIM ← COLWID(IF AREAIXM THEN AREAIXM ELSE IXTEXT)-LMARG ;
MAXIM ← IF FILL THEN FMAXIM ELSE NMAXIM ;
END "COPYMAXIMS" ;
PUBLIC RECURSIVE PROCEDURE EMIT(STRING CHARS) ;$"#
IF ON THEN EMITPIECE(CHARS, LENGTH(CHARS), XLENGTH(CHARS)) ;
PUBLIC RECURSIVE PROCEDURE EMITPIECE(STRING CHARS; INTEGER NCHARS, XCHARL) ;$"#
BEGIN TES PROCEDURIZED 11/29/73 ;
INTEGER EXCHARS, WASBRC ; STRING EXCESS ; LABEL ADDIT ; comment Sorry about that ;
INTEGER XSPCL,XEXCHARS; RKJ;
XSPCL ← XSPLEN(SPCS) ; RKJ;
RKJ: OLD LINE IF POSN + SPCS + NCHARS LEQ MAXIM THEN comment, no overfow ;
IF (IF XCRIBL THEN (XPOSN+XSPCL+XCHARL LEQ XMAXIM) ELSE (POSN+SPCS+NCHARS LEQ MAXIM)) THEN comment no overflow;
ADDIT:
BEGIN
IF SPCS AND XCRIBL AND (FILL AND ADJUST) AND POSN>INDENT THEN
BEGIN FSHORT←FSHORT+XSPLEN(1); SPCS←SPCS-1 END;
IF SPCS THEN BEGIN APPEND(SPS(SPCS)) ; BRKSPCS ← SPCS END ;
APPEND(CHARS) ; POSN ← POSN + SPCS + NCHARS ; SPCS ← 0 ;
XPOSN ← XPOSN + XSPCL + XCHARL; RKJ;
END
ELSE IF FILL AND (BRKPT>INDENT OR BRKPOSN>INDENT) THEN comment, go back to a break point ;
BEGIN
IF BRKPT=OAKS THEN BEGIN XSPCL ← SPCS ← EXCHARS ← 0 ; EXCESS ← NULL END
ELSE BEGIN EXCESS←OWL[BRKPT+1+BRKSPCS TO OAKS]; COPY(EXCESS);
XEXCHARS ← XPOSN-FSHORT-BRKXPOSN-BRKSPCS*XSPLEN(1);
EXCHARS←POSN-BRKPOSN-BRKSPCS END;
FAKE ← FAKE - BRKFAKE ; NOPGPH ← -1 ; WASBRC ← BRC ;
OAKS ← BRKPT ; BOUND(3) ; COMMENT ADDED 4/14/72 ;
PLACELINE(IF OWL[OAKS FOR 1]=WDBRK AND LASTWDBRK=OAKS COMMENT JAN 9 73 ;
THEN OAKS-1 ELSE OAKS, BRKPOSN MIN MAXIM, BRKXPOSN,
BRKFAKE, BRKABX, -BRKBLX, IF FIRST THEN LEADFM ELSE SPREADM-1,
IF FIRST THEN MLEADFM ELSE MSPREADM,
BRKPLBL, ADJUST, SPREADM) ;
FSHORT ← NOPGPH ← OAKS ← TABI ← BRKABX ← BRKBLX ← STARPOSN ← AMPPOSN ← LASTWDBRK ← 0 ; BRC←WASBRC;
COMMENT VARIABLES NEEDED BEYOND THE ABOVE "PLACELINE"
HAD BETTER BE "MIDWDS" IN PUBDFS.SAI ;
IF FIRST THEN BEGIN
INDENT ← RESTIM MAX -LMARG ; FIRST ← FALSE ;
END ;
IF XCRIBL
THEN
BEGIN
APPEND(PICKFONT(BRKFONT)) ; BRKFONT ← THISFONT ; TES 11/16/73 ;
IF (LMARG+INDENT) NEQ 0 THEN APPEND(FONTCHAR&"="&CVSR(CHARW*(LMARG+INDENT)));
XPOSN←CHARW*INDENT;
END
ELSE
BEGIN
APPEND(SPS(LMARG+INDENT));
END;
POSN←INDENT;
IF BRKUNDER THEN BEGIN APPEND(FONTCHAR&"_"); BRKUNDER ← 0 END ; TES 12/28/73;
OKCR(TRUE); TES MOVED AFTER BRKUNDER TEST, 12/28/73 ;
APPEND(EXCESS);
POSN←POSN+EXCHARS; XPOSN←XPOSN+XEXCHARS;
IF SPCS THEN BEGIN OKSP(FALSE) ; OKCR(FALSE) END ;
GO TO ADDIT ;
END
ELSE IF (IF XCRIBL THEN XPOSN LEQ XMAXIM ELSE POSN LEQ MAXIM)
THEN comment, About to overflow right edge of area! ;
BEGIN "LINE TOO LONG"
STRING S; RKJ: 1-5-74;
S←SPS(SPCS)&CHARS; RKJ: 1-5-74;
APPEND((IF XCRIBL THEN (EXCESS←TRUNCATE(S,XMAXIM-XPOSN)) ELSE S[1 TO MAXIM - POSN])) ;
IF XCRIBL AND FNTFIL[DEFAULTFONT]=0 THEN TES 11/15/73;
WARN("=", "FONT declaration needed. Start over!")
ELSE
WARN("Line too long",<(IF NOFILL THEN "Nofill" ELSE "Fill") & " line too long -- characters lost:" &
S[(IF XCRIBL THEN LENGTH(EXCESS)+1 ELSE MAXIM-POSN+1) TO ∞] & "...">) ;
POSN ← MAXIM+1 ; SPCS ← 0 ;
XPOSN ← XMAXIM + 1; RKJ;
END ;
MIDWORD ← MIDWORD OR FULSTR(CHARS) ; PUNC ← FALSE ;
END "EMITPIECE" ;
PUBLIC SIMPLE PROCEDURE EMSPACES(INTEGER N) ;$"#
IF ON THEN BEGIN
IF SPCS=0 THEN BEGIN OKSP(FALSE) ; OKCR(FALSE) END ; MIDWORD ← FALSE ;
SPCS ← IF COMPACT THEN (SPCS+N) MIN (IF PUNC THEN 2 ELSE 1) ELSE SPCS+N ;
END "EMSPACES" ;
PUBLIC SIMPLE PROCEDURE OKCR(BOOLEAN EVEN!IN!SUPERSUBSCRIPT) ;$"#
IF BRKPT NEQ OAKS AND ON AND (SUPERSUB=0 OR EVEN!IN!SUPERSUBSCRIPT) THEN
BEGIN
BRKPT ← OAKS ; BRKPOSN ← POSN ; BRKFAKE ← FAKE ; BRKPLBL ← PLBL ; BRKSPCS ← 0 ;
BRKUNDER ← UNDERLINING ; TES 12/28/73 ;
BRKFONT ← THISFONT ; TES 11/16/73 ;
BRKXPOSN ← XPOSN - FSHORT ;
IF SUPERSUB THEN RETURN ;
BRKABX ← BRKABX MAX ABOVEX ; BRKBLX ← BRKBLX MIN BELOWX ; ABOVEX←BELOWX←0 ;
END "OKCR" ;
PRIVATE SIMPLE PROCEDURE OKSP(BOOLEAN EVEN!BEFORE!LMARG) ;$"#
IF LASTWDBRK NEQ OAKS AND ON AND
JUSTIFY AND (POSN<MAXIM OR XCRIBL) AND (EVEN!BEFORE!LMARG OR POSN > 0 MAX INDENT) THEN
BEGIN APPEND(WDBRK) ; LASTWDBRK ← OAKS ; END ;
PUBLIC RECURSIVE PROCEDURE PGPHSTART ;$"#
IF ON THEN
BEGIN "PGPHSTART"
OAKS←SPCS←TABI←PUNC←MIDWORD←SUPERSUB← 0 ;
ABOVEX←BELOWX←HEIGHT←FAKE←BRKABX←BRKBLX←UNDERLINING← 0 ;
FIRST ← NOFILL OR NOPGPH<0 ;
STARPOSN←AMPPOSN←LASTWDBRK←0 ;
BRKFONT ← THISFONT ; TES 11/16/73 ;
BRKUNDER ← 0 ; TES 12/28/73 ;
INDENT ← IF FLUSHL OR VERBATIM OR CENTER OR FLUSHR THEN 0
ELSE (IF NOFILL OR FIRST THEN FIRSTIM ELSE RESTIM) MAX -LMARG ;
NOPGPH ← 0 ;
LBK ← 3 ; LBF ← NULL ;
IF XCRIBL THEN
BEGIN
APPEND(PICKFONT(THISFONT)) ; TES 11/15/73 ;
IF (LMARG+INDENT) NEQ 0 THEN APPEND(FONTCHAR&"="&CVSR(CHARW*(LMARG+INDENT)));
XPOSN←CHARW*INDENT;
END
ELSE BEGIN
APPEND(SPS(LMARG+INDENT));
END;
POSN←INDENT; FSHORT←0; OKCR(TRUE);
IF FLUSHR THEN BOUND(2) ELSE IF CENTER THEN BOUND(1) ;
FMAXIM ← (RMARG-RIGHTIM)-LMARG ;
NMAXIM ← COLWID(IF AREAIXM THEN AREAIXM ELSE IXTEXT) - LMARG ;
MAXIM ← IF FILL THEN FMAXIM ELSE NMAXIM ;
END "PGPHSTART" ;
PUBLIC STRING SIMPLE PROCEDURE SPS(INTEGER N) ;$"#
IF N LEQ 10 THEN RETURN(SPSARR[N MAX 0])
ELSE RETURN(SPSSTR[1 TO N]) ;
PUBLIC INTERNAL RECURSIVE BOOLEAN PROCEDURE TEXTLINE ;$"#
BEGIN
PRELOAD!WITH 6, [8]0, 1, [2]0, 5, 0, 3, [4]4, [6]0, 4, 2, 4, 2, [2]0 ;
OWN INTEGER ARRAY TEXTTYPE[-15:15] ;
BOOLEAN IMITEXT ; INTEGER USYMB, LEN ; STRING STR ;
IMITEXT ← TRUE ; comment assume computed text line ;
CASE TEXTTYPE[THISTYPE] OF
BEGIN COMMENT BY TYPE ;
COMMENT 0 ... Invalid ; RETURN(FALSE) ;
COMMENT 1 ... [ ; BEGIN comment [Est] Label or [@] rubout gen-label ; PASS ;
IF ITSCH(@) THEN BEGIN PASS ; IMITEXT ← FALSE END
ELSE BEGIN LEN ← CVD(E("5", 0)) ; COMMENT THANKS RKJ ;
IF ITSCH(<]>) THEN PASS ELSE
WARN("=",<"Missed ] after label length; You probably thought you had" & CRLF &
"a subscripted variable like X[I] computing text;" & CRLF &
"but the syntax of that would be (X[I]). See" & CRLF &
"p.21 in the manual for parenthesis rules.">) ;
THISWD ← LABELREF(0, LEN) ; END ;
END ;
COMMENT 2 ... Unit ; IF THATISID THEN
BEGIN comment Unit Label ;
USYMB ← SYMB ;
LEN ← IF THISTYPE=PCOUNTERTYPE THEN PATT!CHRS(IX) ELSE CTR!CHRS(IX) ;
PASS ; THISWD ← LABELREF(USYMB, LEN) ;
END
ELSE IF IX=IXPAGE THEN
BEGIN comment, Generate a label ;
THISWD ← NULL ;
THISWD ← LABELREF(0, IF ITS(PAGE) THEN CTR!CHRS(IXPAGE) ELSE PATT!CHRS(IXPAGE)) ;
END
ELSE THISWD ← VEVAL ;
COMMENT 3 ... Constant ;
BEGIN
LOPP(THISWD) ; STR ← THISWD ; TES 8/19/74 FIX BUG ;
IF THATISID AND SIMLOOK(CAPITALIZE(STR←SCAN(STR,ALPHA,DUMMY)))
AND (SYMTYPE = COUNTERTYPE OR SYMTYPE = PCOUNTERTYPE) THEN
BEGIN comment "Unit.." Label ;
IF SYMTYPE=PCOUNTERTYPE THEN STR←STR[1 TO ∞-1]; USYMB ← SYMBOL;
LEN ← IF SYMTYPE=PCOUNTERTYPE THEN PATT!CHRS(SYMIX) ELSE CTR!CHRS(SYMIX) ;
PASS ; THISWD ← STR & SP & LABELREF(USYMB, LEN) ;
END ;
END ;
COMMENT 4 ... Variable ; THISWD ← VEVAL ;
COMMENT 5 ... } etc. ; IF IX comment not } ; THEN RETURN(FALSE) ELSE IMITEXT←FALSE ;
COMMENT 6 ... misc ; IF ITSCH(<(>) THEN BEGIN PASS; STR←E(NULL,NULL);
IF NOT ITSCH(<)>) THEN WARN("=","Parens don't match") ; THISWD←STR END ELSE RETURN(FALSE) ;
END ; COMMENT BY TYPE ;
IF IMITEXT THEN IF NULSTR(THISWD) OR NOT ON THEN ELSE
BEGIN
BEGINBLOCK(FALSE, 0, "COMPUTED!TEXT") ;
SWICH(THISWD&ALTMODE&" END ""COMPUTED!TEXT""", -1, 0) ;
TEXTSEGMENT ;
END
ELSE TEXTSEGMENT ;
PASS ;
RETURN(TRUE) ;
END "TEXTLINE" ;
PRIVATE RECURSIVE PROCEDURE TEXTSEGMENT ;$"#
BEGIN
INTEGER INSET, N ;
EMPTYTHIS ; INSET ← 0 ;
IF INPUTSTR = VT THEN IF NOT ON THEN LOPP(INPUTSTR) ELSE
BEGIN "NEW INPUT LINE"
LOPP(INPUTSTR) ;
IF VERBATIM THEN BEGIN END
ELSE IF INPUTSTR=CR AND (N←SIGNALD[CR]) THEN BEGIN LOPP(INPUTSTR) ; RESPOND(N) ; RETURN END
ELSE IF ATLEAD(INSET ← LENGTH(RD(TO!NON!SP))) THEN INSET←0 ; comment AT NULL , AT <integer> ;
END "NEW INPUT LINE" ;
IF NOPGPH THEN
BEGIN
PGPHSTART ; TES 11/2/74 PROCEDURIZED ;
IF ON AND VERBATIM THEN
BEGIN
JUSTIFY←FALSE;
EMIT(RD(TO!CR!SKIP));
DBREAK ;
RETURN ;
END ;
END ;
JUSTIFY ← FILL AND ADJUST OR JUSTJUST ;
IF INSET AND RETAIN AND NOT FLUSHL THEN EMSPACES(INSET) ;
SCANTEXT ;
END "TEXTSEGMENT " ;
FINISHED
ENDOF("FILLR")